package work

import "sync"

// Worker interface 必须满足worker的要求才能使用工作池
type Worker interface {
	Task()
}

// Pool 提供一个goroutine池，这个池可以完成任何已提交的woker任务
type Pool struct {
	work chan Worker
	wg   sync.WaitGroup
}

// New 创建一个工作池
func New(maxGoroutine int) *Pool {
	p := Pool{
		work: make(chan Worker),
	}
	p.wg.Add(maxGoroutine)
	for i := 0; i < maxGoroutine; i++ {
		go func() {
			// 一直循环取任务，直到work被关闭为止
			for w := range p.work {
				w.Task()
			}
			// 退出时候，减少一个计数器
			p.wg.Done()
		}()
	}
	return &p
}

// Run 将任务放入工作池
func (p *Pool) Run(w Worker) {
	p.work <- w
}

// Shutdown 等待所有goroutine完成工作
func (p *Pool) Shutdown() {
	// 关闭work所有协程完成任务之后会退出for循环
	close(p.work)
	p.wg.Wait()
}
